package com.project.ToDone;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MapView.LayoutParams; 
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.ItemizedOverlay;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.omg.CORBA.portable.InputStream;

import android.location.Address;
import android.location.Geocoder;

//import com.sun.tools.javac.util.List;

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.EditText;
import android.widget.TextView;
/**
 * This class sets up the google map for our application
 *
 *
 */
public class GoogleMapsActivity extends MapActivity {


	private Button locationSearchButton;
	private EditText addressField;
	private List<Overlay> mapOverlays;
	private ArrayList<String> locationList;
	private ArrayList<GeoPoint> geoList;
	private Drawable drawable;
	private AddItemizedOverlay itemizedOverlay;
	private MapView mapView;
	
	/** Called when the activity is first created. */
	@Override
	/**
	 * Oncreate loads the map.xml and sets the default view to be over atlanta.
	 * @param savedInstanceState the Bundle being passed in
	 */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		 //set default screen to map
		setContentView(R.layout.map);
		//set up the mapView and zooming
		mapView = (MapView) findViewById(R.id.mapView);
        mapView.setBuiltInZoomControls(true);  
        
       // This *SHOULD* create a geoPoint and animate to the specified lat/long. It doesn't.
        MapController mc = mapView.getController();
        double lat = Double.parseDouble("33.85827758964043"); // latitude
        double lon = Double.parseDouble("-84.294543981552124"); // longitude
        GeoPoint geoPoint = new GeoPoint((int)(lat * 1E6), (int)(lon * 1E6));
        mc.animateTo(geoPoint);
        mc.setZoom(10);
        mapView.invalidate();
        
        //Instantiate better stuff
		mapOverlays = mapView.getOverlays();
		drawable = this.getResources().getDrawable(R.drawable.ic_launcher);
		itemizedOverlay = new AddItemizedOverlay(drawable);
        
		ArrayList<String> location = MasterControlProgram.getLocations();
		ArrayList<OverlayItem> overlays = new ArrayList<OverlayItem>();
		
		
		for(String s: location){
			if(s!=null){
				
				GeoPoint p = createGeoPoint(s);
				if(p!=null){
					overlays.add(new OverlayItem(p, "", ""));
				}
				
				
			}
		}
		
		for(OverlayItem o: overlays){
			itemizedOverlay.addOverlay(o);
		}
		
		//GeoPoint point = new GeoPoint(19240000,-99120000);
		//OverlayItem overlayitem = new OverlayItem(point, "Hola, Mundo!", "I'm in Mexico City!");
		
		//GeoPoint point2 = new GeoPoint(35410000, 139460000);
		//OverlayItem overlayitem2 = new OverlayItem(point2, "Sekai, konichiwa!", "I'm in Japan!");
		
		
		//itemizedOverlay.addOverlay(overlayitem);
		//itemizedOverlay.addOverlay(overlayitem2);
		mapOverlays.add(itemizedOverlay);
		
 
 
		
		Button listButton = (Button)findViewById(R.id.back_to_list_button);	
		//Sets listener for back to list button. 
		listButton.setOnClickListener(
				new View.OnClickListener() {
					
					
					/**
					 * This method determines what is done upon click on the
					 * List button. 
					 * 
					 * @param View v
					 */
					public void onClick(View v) {
						finish();
						}
					});
		
					
	}



	@Override
	/**
	 * This is just an inherited method that has to be overwritten. It just returns false.
	 * @return false
	 */
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	/**
	 * This method sets the maps location and level of zoom over a specified geoPoint
	 * 
	 * @param p The geopoint being focused on
	 */
	private void zoomToGeopoint(GeoPoint p) {
		mapView.getController().animateTo(p);
		//mapView.getController().setZoom(15);

		OverlayItem overlayitem = new OverlayItem(p, "", "");
		//FIX THIS LATER
		//itemizedOverlay.setOverlay(overlayitem);
		mapOverlays.add(itemizedOverlay);
	}
	
	/**
	 * This inner class is used to set up the overlay items (pins) on the map
	 * 
	 *
	 */
	private class LocationItemizedOverlay extends ItemizedOverlay {
		private OverlayItem	location;
		
		/**
		 * This sets up the drawable marker
		 * @param marker
		 */
		public LocationItemizedOverlay(Drawable marker) {
			super(boundCenterBottom(marker));
		}
		/**
		 * This sets the location to be overlay and populates it
		 * @param overlay
		 */
		public void setOverlay(OverlayItem overlay) {
			location = overlay;
			populate();
		}
		/**
		 * This creates an item and returns a location
		 */
		protected OverlayItem createItem(int i) {
			return location;
		}
		/**
		 * This just returns 1
		 * @return 1
		 */
		public int size() {
			return 1;
		}
	}
	
	/**
	 * The createGeoPoint takes in an addressText, be it a specific address or a gerneral location, like a city,
	 * and creates a geoPoint at that location.
	 * @param addressText the desired location of the geopoint
	 * @return GeoPoint the created geoPoint
	 */
	private GeoPoint createGeoPoint(String addressText) {
		// use android's geocoder implementation to find a location
		Geocoder geocoder = new Geocoder(this, Locale.US);
		//System.out.println("One");
		GeoPoint p = null;
		try {
			//System.out.println("BO" + addressText + "WOAH");
			List<Address> addresses = geocoder.getFromLocationName(addressText, 5);
			//System.out.println("Two");
			if (addresses.size() > 0) {
				// use the first address as the location
				p = new GeoPoint((int) (addresses.get(0).getLatitude() * 1E6), (int) (addresses.get(0).getLongitude() * 1E6));
			}
		} catch (IOException e) {

			// Geocoder will thrown an IOException if it's not supported on the platform
			// Really, platforms should define the

			Log.w("LocationView", "Geocoder failed with message: " + e.getMessage());
			Log.w("LocationView", "Attempting Google Maps API workaround.");

			try {
				p = getGeoPoint(getLocationInfo(addressText));
			} catch (ClientProtocolException e1) {
				Log.w("LocationView", "Maps API failed with message: " + e1.getMessage());
			} catch (JSONException e1) {
				Log.w("LocationView", "Maps API failed with message: " + e1.getMessage());
			} catch (Exception e1) {
				Log.w("LocationView", "Maps API failed with message: " + e1.toString());
			}
		}

		return p;

	}
	
	/**
	 * This method gets info on the location
	 * @param address
	 * @return JSONObject
	 * @throws JSONException
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static JSONObject getLocationInfo(String address) throws JSONException, ClientProtocolException, IOException {

		// right now, we're uri-encoding spaces
		// we really should check all the characters which are changed by uri encoders
		HttpGet httpGet = new HttpGet("http://maps.google.com/maps/api/geocode/json?address="
				+ address.replaceAll(" ", "%20") + "ka&sensor=false");
		HttpClient client = new DefaultHttpClient();
		HttpResponse response;
		StringBuilder stringBuilder = new StringBuilder();

		response = client.execute(httpGet);
		HttpEntity entity = response.getEntity();
		java.io.InputStream stream = entity.getContent();
		int b;
		while ((b = stream.read()) != -1) {
			stringBuilder.append((char) b);
		}

		JSONObject jsonObject = new JSONObject();
		jsonObject = new JSONObject(stringBuilder.toString());

		return jsonObject;
	}
	
	/**
	 * This is just a getter for a geoPoint
	 * @param jsonObject
	 * @return GeoPoint
	 * @throws JSONException
	 */
	public static GeoPoint getGeoPoint(JSONObject jsonObject) throws JSONException {

		Double lon = new Double(0);
		Double lat = new Double(0);

		if (((JSONArray) jsonObject.get("results")).length() == 0) {
			return null;
		}

		lon = ((JSONArray) jsonObject.get("results")).getJSONObject(0).getJSONObject("geometry").getJSONObject("location")
				.getDouble("lng");

		lat = ((JSONArray) jsonObject.get("results")).getJSONObject(0).getJSONObject("geometry").getJSONObject("location")
				.getDouble("lat");

		return new GeoPoint((int) (lat * 1E6), (int) (lon * 1E6));
	}
	/**
	 * This closes the current screen.
	 * @param view
	 */
	public void confirm(View view) {
		finish();
	}

}
